package com.ccteam.fluidmusic.ui.nowplaying

import android.content.res.ColorStateList
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.annotation.LayoutRes
import androidx.core.view.isVisible
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import androidx.fragment.app.viewModels
import androidx.recyclerview.widget.DiffUtil
import com.bumptech.glide.Glide
import com.ccteam.fluidmusic.R
import com.ccteam.fluidmusic.databinding.FragmentPlaylistPlayerBinding
import com.ccteam.fluidmusic.databinding.NowPlayingPlaylistItemBinding
import com.ccteam.fluidmusic.view.adapters.databinding.DataBindAdapter
import com.ccteam.fluidmusic.view.adapters.databinding.DataBindViewHolder
import com.ccteam.fluidmusic.view.bean.LoadMessage
import com.ccteam.fluidmusic.view.bean.PlaylistMediaData
import com.ccteam.fluidmusic.ui.MainActivityViewModel
import com.google.android.material.color.MaterialColors
import dagger.hilt.android.AndroidEntryPoint
import kotlin.math.min

@AndroidEntryPoint
class PlaylistPlayerFragment : Fragment() {

    /**
     * 由于ViewPager转场时就加载数据会导致卡顿，所以判断是否是第一次加载，如果是延迟一点进行加载
     */
    private var isFirstLoad: Boolean = true

    private val mainActivityViewModel by activityViewModels<MainActivityViewModel>()

    /**
     * 因为此Fragment在ViewPager中，需要使用parentFragment的生命周期共享这个ViewModel
     */
    private val nowPlayingViewModel by viewModels<NowPlayingViewModel>(ownerProducer = { parentFragment ?: this})

    private var _binding: FragmentPlaylistPlayerBinding? = null
    private val binding get() = _binding!!

    private val adapter = PlaylistQueueListAdapter(PlaylistMediaData.diffCallback,
        R.layout.now_playing_playlist_item)

    companion object {

        @JvmStatic
        fun newInstance(): PlaylistPlayerFragment {
            return PlaylistPlayerFragment()
        }
    }

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        _binding = FragmentPlaylistPlayerBinding.inflate(inflater,container,false)
        return binding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {

        nowPlayingViewModel.enableFluidMode.observe(viewLifecycleOwner, {
            adapter.updateFluidMode(it)
        })

        binding.rvPlaylistQueue.adapter = adapter

    }

    override fun onResume() {
        super.onResume()
        if(isFirstLoad){
            observePlaylist()
            isFirstLoad = false
        }

    }

    private fun observePlaylist(){
        mainActivityViewModel.playlistMediaData.observe(viewLifecycleOwner, {
            // 如果播放列表为空，则显示空状态提示
            binding.statusView.isVisible = it.isNullOrEmpty()
            if(it.isNullOrEmpty()){
                binding.statusView.changeToErrorStatus(LoadMessage.Empty)
            }
            adapter.submitList(it)
            if(isFirstLoad){
                // 滑动到对应位置
                binding.rvPlaylistQueue.scrollToPosition(
                    mainActivityViewModel.currentItemInPlaylistIndex - min(2,adapter.itemCount)
                )
                binding.progressPlaylist.hide()
            }
        })
    }

    override fun onDestroyView() {
        super.onDestroyView()
        isFirstLoad = true
        _binding = null
    }

    private val playlistItemClick = object: PlaylistItemClickCallback {

        override fun playlistItemClicked(view: View, playlistItem: PlaylistMediaData) {
            mainActivityViewModel.skipQueueItem(playlistItem.queueId)
        }

        override fun removeQueueItemClick(playlistItem: PlaylistMediaData) {
            mainActivityViewModel.removeQueueItem(playlistItem.queueId)
        }

    }

    inner class PlaylistQueueListAdapter(
        diffCallback: DiffUtil.ItemCallback<PlaylistMediaData>,
        @LayoutRes layoutRes: Int
    ): DataBindAdapter<NowPlayingPlaylistItemBinding, PlaylistMediaData>(diffCallback,layoutRes) {

        private var fluidMode = true

        fun updateFluidMode(fluidMode: Boolean){
            this.fluidMode = fluidMode
            notifyDataSetChanged()
        }

        override fun bindItem(
            holder: DataBindViewHolder<NowPlayingPlaylistItemBinding>,
            position: Int,
            payloads: MutableList<Any>?
        ) {
            val item = getItem(position)

                holder.binding.playlistQueueItem = item
                holder.binding.callback = playlistItemClick

                val textColor = if(fluidMode){
                    requireContext().getColor(R.color.white_alphaf0)
                } else {
                    MaterialColors.getColor(holder.itemView,R.attr.colorOnSurface)
                }
                holder.binding.tvMusicSubtitle.setTextColor(textColor)
                holder.binding.tvMusicTitle.setTextColor(textColor)
                updateSelectColor(holder,item)
                Glide.with(holder.binding.ivThumbnailAlbumArt)
                    .load(item.albumArtUri)
                    .placeholder(R.drawable.img_default_album)
                    .into(holder.binding.ivThumbnailAlbumArt)

        }

        private fun updateSelectColor(holder: DataBindViewHolder<NowPlayingPlaylistItemBinding>,
                                      item: PlaylistMediaData){

            if(item.isPlaying){
                if(fluidMode){
                    holder.binding.root.backgroundTintList = ColorStateList.valueOf(
                        requireContext().getColor(R.color.white_alpha2e)
                    )
                } else {
                    holder.binding.root.backgroundTintList = ColorStateList.valueOf(
                        requireContext().getColor(R.color.defaultPlaylistSelectColor)
                    )
                }
            } else {
                val normalColor = if(fluidMode){
                    requireContext().getColor(android.R.color.transparent)
                } else {
                    MaterialColors.getColor(holder.itemView,R.attr.colorSurface)
                }
                holder.binding.root.backgroundTintList = ColorStateList.valueOf(
                    normalColor
                )
            }
        }

    }

    interface PlaylistItemClickCallback{
        fun playlistItemClicked(view: View,playlistItem: PlaylistMediaData)
        fun removeQueueItemClick(playlistItem: PlaylistMediaData)
    }
}